package com.example.mall.common.handler;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.postgresql.util.PGobject;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Mickey
 * @since 2022/4/13
 **/
@Slf4j
@AllArgsConstructor
public abstract class ArrayTypeHandler<T> extends BaseTypeHandler<List<T>> {

    private final ObjectMapper objectMapper;

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType)
            throws SQLException {
        if (ps != null) {
            PGobject pGobject = new PGobject();
            pGobject.setType("jsonb");
            try {
                pGobject.setValue(objectMapper.writeValueAsString(parameter));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            ps.setObject(i, pGobject);

        }
    }

    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return getArray(rs.getArray(columnName));
    }


    @Override
    public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return getArray(rs.getArray(columnIndex));
    }


    @Override
    public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return getArray(cs.getArray(columnIndex));
    }

    private List<T> getArray(Array array) {

        if (array == null) {
            return new ArrayList<>();
        }


        try {
            return objectMapper.readValue(array.toString(), getType());
        } catch (JsonProcessingException e) {
            log.error("类型转换异常 = {}", e.getMessage());
        }
        return new ArrayList<>();
    }

    public TypeReference<List<T>> getType() {
        return null;
    }

}
